package com.weavernorth.action.paymentSlip;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.weavernorth.action.paymentSlip.pojo.*;
import com.weavernorth.action.paymentSlip.utils.ApiSign;
import com.weavernorth.util.HttpUtil;
import com.weavernorth.util.Logger4jUtil;
import org.apache.commons.beanutils.BeanMap;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.log4j.Logger;
import weaver.conn.RecordSet;
import weaver.general.BaseBean;
import weaver.general.Util;
import weaver.interfaces.workflow.action.Action;
import weaver.soa.workflow.request.RequestInfo;
import weaver.wechat.util.Utils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.weavernorth.util.dateUtils.getNowDateTime;

/**
 * @Author: bruseewang
 * @Package: com.weavernorth.action.paymentSlip
 * @date: 2021/9/23 14:29
 * @description: 付款单确认接口一对多：BPM系统将一家公司对多家供应商的付款信息推送绒信系统，绒信系统进行校验，
 * 返回给BPM对每一家供应商是否可付款的结果，BPM根据返回结果，控制是否可提交流程。
 */
public class paymentSlipMany implements Action {

    @Override
    public String execute(RequestInfo requestInfo) {
        Logger log = new Logger4jUtil().getLogger("/action/paymentSlipMany/");
        BaseBean bb=new BaseBean();
        log.info("付款单确认接口一对多（BPM——>绒信平台）begin===>");
        //请求id
        String strRequestid = requestInfo.getRequestid();
        log.info("流程requestid="+strRequestid);
        String strTable = requestInfo.getRequestManager().getBillTableName();
        log.info("流程主表="+strTable);
        String strResponseBody = "";
        try {
            //根据requestid获取主表信息
            String strQuery = " select a.fkdwtyshxydm,b.skdwshtyxydm,b.bcfkje,b.sfsjblyw,b.skdwqc from " + strTable + " a,"+strTable+"_dt1 b where a.id=b.mainid and a.requestid="+strRequestid;
            log.info("获取数据sql:"+strQuery);
            RecordSet rs = new RecordSet();
            rs.executeQuery(strQuery);
            String payerCode = "";//付款单位统一社会信用代码
            String payeeCode = "";//收款单位统一社会信用代码
            String sfsjblyw="";//是否涉及保理业务
            String skdwqc="";//收款单位名称
            List<paymentPoJo> paymentPoJoList=new ArrayList<>();
            paymentPoJo pojo;
            while (rs.next()) {
                skdwqc = Utils.null2String(rs.getString("skdwqc"));
                log.info("收款单位名称："+skdwqc);
                payerCode = Utils.null2String(rs.getString("fkdwtyshxydm"));
                log.info("付款单位统一社会信用代码：" + payerCode);
                payeeCode = Utils.null2String(rs.getString("skdwshtyxydm"));
                log.info("收款单位统一社会信用代码：" + payeeCode);
                sfsjblyw = Utils.null2String(rs.getString("sfsjblyw"));
                log.info("是否涉及保理业务："+sfsjblyw);
                String str_amount="0.00";
                str_amount= Util.null2String(rs.getString("bcfkje"),"0.00");//取付款金额
                BigDecimal b_amount=new BigDecimal(str_amount);
                log.info("付款金额：" + b_amount.toString());//保留小数点后两位
                if(sfsjblyw.equals("0")) {
                    pojo = new paymentPoJo();
                    pojo.setPayerCompanyCreditNo(payerCode);
                    pojo.setPayeeCompanyCreditNo(payeeCode);
                    pojo.setAmount(b_amount.toString());
                    pojo.setSkdwqc(skdwqc);
                    paymentPoJoList.add(pojo);

                }
            }
            if(paymentPoJoList.size()>0) {
                List<paymentPoJo> paymentList=new ArrayList<>();
                //根据收款单位分组
                Map<String, List<paymentPoJo>> collect = paymentPoJoList.stream().collect(Collectors.groupingBy(paymentPoJo::getSkdwqc));
                for (String key : collect.keySet()) {
                    List<paymentPoJo> paymentPoJos = collect.get(key);
                    BigDecimal tem_amount = new BigDecimal("0.00");//付款金额
                    for(int i=0;i<paymentPoJos.size();i++){
                        BigDecimal mount=new BigDecimal(paymentPoJos.get(i).getAmount());
                        tem_amount = tem_amount.add(mount);
                        if(i==paymentPoJos.size()-1){
                            paymentPoJo temp_pojo = new paymentPoJo();
                            temp_pojo.setPayerCompanyCreditNo(paymentPoJos.get(i).getPayerCompanyCreditNo());
                            temp_pojo.setPayeeCompanyCreditNo(paymentPoJos.get(i).getPayeeCompanyCreditNo());
                            temp_pojo.setSkdwqc(paymentPoJos.get(i).getSkdwqc());
                            temp_pojo.setAmount(tem_amount.toString());
                            paymentList.add(temp_pojo);
                        }

                    }
                }
                if(paymentList.size()>0) {
                    log.info("根据收款单位名称分组汇总："+paymentList.toString());
                    //根据付款单位分组
                    Map<String, List<paymentPoJo>> collect_pay = paymentList.stream().collect(Collectors.groupingBy(paymentPoJo::getPayerCompanyCreditNo));
                    List<payerCompanyVo> list_result=new ArrayList<>();
                    for (String key : collect_pay.keySet()) {
                        List<paymentPoJo> paymentPoJos = collect_pay.get(key);
                        List<payeePojo> list_temp=new ArrayList<>();
                        payerCompanyVo payer=new payerCompanyVo();
                        payer.setPayerCompanyCreditNo(key);

                        for(int i=0;i<paymentPoJos.size();i++){
                            payeePojo temp_pojo=new payeePojo();
                            temp_pojo.setPayeeCompanyCreditNo(paymentPoJos.get(i).getPayeeCompanyCreditNo());
                            temp_pojo.setAmount(paymentPoJos.get(i).getAmount());
                            list_temp.add(temp_pojo);

                        }
                        payer.setPayeeCompanyCreditNos(list_temp);
                        list_result.add(payer);
                    }
                    log.info("根据付款单位名称分组汇总："+list_result.toString());


                    String url = bb.getPropValue("payMentSlipProps", "url_many");
                    log.info("绒信接口url地址=" + url);
                    String appid = bb.getPropValue("payMentSlipProps", "app_id");
                    String app_secret = bb.getPropValue("payMentSlipProps", "app_secret");
                    log.info("app_secret=" + app_secret);
                    String timestamp = getNowDateTime();//获取当前时间戳
                    Map<String, Object> params = new HashMap<>();
                    params.put("appId", appid);
                    params.put("timestamp", timestamp);
                    String str_sign = ApiSign.fddParam(appid, timestamp, app_secret, params);
                    queryParams query = new queryParams();
                    query.setAppId(appid);
                    query.setSign(str_sign);
                    query.setTimestamp(timestamp);
                    query.setList(list_result);

                    ObjectMapper objectMapper = new ObjectMapper();
                    //jackson将java对象序列化
                    String object = objectMapper.writeValueAsString(query);
                    log.info("传入接口参数：" + object.toString());
                    strResponseBody = HttpUtil.doPost(url, object.toString());
                    log.info("返回结果:" + strResponseBody);
                    JSONObject jsonResult = JSONObject.parseObject(strResponseBody);
                    dataTwoVo resultMessage = JSONObject.toJavaObject(jsonResult, dataTwoVo.class);
                    log.info("返回结果转为实体对象：" + resultMessage.toString());
                    String returnMessage = "";
                    if (resultMessage.getResp_code() == 200) {
                        log.info("付款单确认接口一对多（BPM——>绒信平台）end===");
                        List<DataPoJo> dataList = resultMessage.getData();
                        for (DataPoJo dataPoJo : dataList) {
                            if (dataPoJo.getStatus() != 1) {
                                String tyxydm=dataPoJo.getPayeeCompanyCreditNo();//收款单位统一社会信用代码
                                String remarks=dataPoJo.getRemarks();//接口返回错误信息
                                String strSkdwqc="";//收款单位全称
                                log.info("[收款单位统一社会信用代码:" + tyxydm + ":" + remarks + "]");
                                List<paymentPoJo> poJoList = paymentList.stream().filter(v -> v.getPayeeCompanyCreditNo().equals(tyxydm)).collect(Collectors.toList());
                                for (paymentPoJo p : poJoList) {
                                    strSkdwqc=p.getSkdwqc();
                                }
                                if("".equals(strSkdwqc)){
                                    returnMessage += "收款单位统一社会信用代码：" + tyxydm + ",接口信息：" + remarks;
                                }else {
                                    returnMessage += "收款单位名称：" + strSkdwqc + ",接口信息：" + remarks;
                                }

                            }
                        }
                        if (!"".equals(returnMessage)) {
                            requestInfo.getRequestManager().setMessagecontent(returnMessage);
                            return FAILURE_AND_CONTINUE;
                        }

                    } else {
                        if (resultMessage.getData() != null) {
                            requestInfo.getRequestManager().setMessagecontent("接口返回错误信息：" + returnMessage.toString());
                        } else {
                            requestInfo.getRequestManager().setMessagecontent(resultMessage.getResp_msg());
                        }
                        return FAILURE_AND_CONTINUE;
                    }
                }
            }
        }catch (Exception ex){
            log.info("程序异常，异常信息："+ex.toString());
            log.info("付款单确认接口一对多（BPM——>绒信平台）end===");
            requestInfo.getRequestManager().setMessagecontent(ex.toString());
            return FAILURE_AND_CONTINUE;
        }
        log.info("付款单确认接口一对多（BPM——>绒信平台）end===");
        return SUCCESS;
    }
}
